package PrjDBConf

import (
	"database/sql"
	"dgo/MyProj/PrjDBUtils"
	"dgo/MyProj/PrjHttpUtils"
	db_utils "dgo/goutils/db-utils"
	"dgo/goutils/utils"
	"fmt"
	"gitee.com/ymofen/supervalue"
	"net/http"
)

var (
	CheckHttpRequestEntryFunc func(w http.ResponseWriter, r *http.Request) bool = nil
	DBConf_DB_ID              string                                            = "main"
)

func checkHttpRequest(w http.ResponseWriter, r *http.Request) bool {
	if CheckHttpRequestEntryFunc != nil {
		return CheckHttpRequestEntryFunc(w, r)
	} else {
		return true
	}
}

/*
	{
	   "id":"xxx",
	}
*/
func OnHttpDbConfUpdate(w http.ResponseWriter, r *http.Request) {
	PrjHttpUtils.AllowCrossAccessSet(w)
	if utils.GoFunCatchException {
		defer utils.PanicHandler()
	}

	reqHttp := PrjHttpUtils.NewHttpRec(w, r)
	reqHttp.Req = PrjHttpUtils.GetBodyAsJSON2(r)

	strAppID, strTypeID, strConf := reqHttp.QryAsString("appid", ""), reqHttp.QryAsString("typeid", ""), reqHttp.QryAsString("config", "")

	var err error
	isBreak := false
	if OnConfUpdate != nil {
		isBreak := true
		err = OnConfUpdate(reqHttp, strAppID, strTypeID, strConf, &isBreak)
		if err != nil {
			PrjHttpUtils.ResponseCodeAndMsg(w, -1, err.Error())
			return
		}
	}

	if !isBreak {
		if err := AppConfService.CheckEnv(); err != nil {
			PrjHttpUtils.ResponseCodeAndMsg(w, -1, err.Error())
			return
		}
		err := AppConfService.ConfUpdate(strAppID, strTypeID, strConf)
		if err != nil {
			PrjHttpUtils.ResponseCodeAndMsg(w, -1, fmt.Sprintf("更新配置出现异常:%s", err.Error()))
			return
		}
	}
	PrjHttpUtils.ResponseCodeAndMsg(w, 0, "")
}

func OnHttpDbConfQryRec(w http.ResponseWriter, r *http.Request) {
	PrjHttpUtils.AllowCrossAccessSet(w)
	if utils.GoFunCatchException {
		defer utils.PanicHandler()
	}

	if err := AppConfService.CheckEnv(); err != nil {
		PrjHttpUtils.ResponseCodeAndMsg(w, -1, err.Error())
		return
	}

	reqHttp := PrjHttpUtils.NewHttpRec(w, r)
	reqHttp.Req = PrjHttpUtils.GetBodyAsJSON2(r)
	strRecID := PrjHttpUtils.GetReqParamAsString(r, reqHttp.Req, "id", "")
	sqlB := db_utils.NewSQLBuilder()
	sqlB.SelectFields("fid, ftypeid, fappid, fcaption, fconfig, flastuptime").From("sys_config")
	if len(strRecID) > 0 {
		sqlB.Where()
		sqlB.EqualValues("fid", strRecID)
	}

	sqlB.OrderBy().Desc("flastuptime")
	lvsql := sqlB.String()

	blockItm := PrjDBUtils.DbBlocker.BeginUse2()
	defer blockItm.EndUse()
	db, err := PrjDBUtils.GetDB(DBConf_DB_ID)
	if err != nil {
		PrjHttpUtils.ResponseCodeAndMsg(w, -1, err.Error())
		return
	}
	defer db.Close()

	lst, cols, err := PrjDBUtils.GetRowListWithColumns(db, lvsql)
	if err != nil {
		PrjHttpUtils.ResponseCodeAndMsg(w, -1, err.Error())
		return
	}
	if len(lst) > 0 {
		rlist := reqHttp.Resp.ForceArrayByPath("list")
		PrjDBUtils.JsonCopyFromRowsAndColumn2(rlist, lst, cols)
	}

	reqHttp.Resp.SetKeyInt("code", 0)
	reqHttp.ResponseAsJSON()
}

// 0 不新建, 1: 新建(如果appid对应不存在), 10: 新建Type(如果不存在则新建)
func NewDBConfRec(db *sql.DB, id, typeid, appid string, newflag int) error {
	if newflag == 0 {
		return nil
	}
	if len(id) == 0 {
		id = utils.RandHexString(38)
	}
	recB := db_utils.NewRecUpdateUpbuilder()
	recB.SetValues("fid", id, "ftypeid", typeid)
	if newflag == 1 { // 设置appid
		recB.SetValues("fappid", appid)
	}

	lvsql := recB.BuildInsert("sys_config")
	_, err := PrjDBUtils.ExecSql(db, lvsql)
	return err
}

func OnHttpDbConfGet(w http.ResponseWriter, r *http.Request) {
	PrjHttpUtils.AllowCrossAccessSet(w)
	if utils.GoFunCatchException {
		defer utils.PanicHandler()
	}

	if err := AppConfService.CheckEnv(); err != nil {
		PrjHttpUtils.ResponseCodeAndMsg(w, -1, err.Error())
		return
	}

	reqHttp := PrjHttpUtils.NewHttpRec(w, r)
	reqHttp.DecodeRequestBodyAsJSON()
	//reqHttp.Req = PrjHttpUtils.GetBodyAsJSON2(r)
	strAppID := PrjHttpUtils.GetReqParamAsString(r, reqHttp.Req, "appid", "")
	strTypeID := PrjHttpUtils.GetReqParamAsString(r, reqHttp.Req, "typeid", "")
	strConfAsType := PrjHttpUtils.GetReqParamAsString(r, reqHttp.Req, "confAs", "json")
	isMainList := reqHttp.QryAsBool("mainlist", false)

	// 0 不新建, 1: 新建(如果appid对应不存在), 10: 新建Type(如果不存在则新建)
	newFlag := PrjHttpUtils.GetReqParamAsInt(r, reqHttp.Req, "newflag", 0)
	if len(strTypeID) == 0 {
		reqHttp.SetValues("code", -1, "msg", "必须指定TYPEID参数")
		reqHttp.ResponseAsJSON()
		return
	}

	var err error
	var rval interface{}
	if OnGetConf != nil {
		isBreak := true
		err, rval = OnGetConf(reqHttp, strAppID, strTypeID, strConfAsType, int(newFlag), &isBreak)
		if !isBreak {
			err, rval = AppConfService.GetConf(strAppID, strTypeID, strConfAsType, int(newFlag))
		}
	} else {
		err, rval = AppConfService.GetConf(strAppID, strTypeID, strConfAsType, int(newFlag))
	}

	if err != nil {
		reqHttp.SetValues("code", -1, "msg", err.Error())
		reqHttp.ResponseAsJSON()
	} else {
		if rval == nil {
			if isMainList {
				lst := reqHttp.Resp.ForceArrayByPath("list")
				itm := lst.AppendObject()
				itm.SetKeyString("id", strAppID)
				itm.SetKeyString("appid", strAppID)
				itm.SetKeyString("typeid", strTypeID)
				itm.SetKeyString("confAs", "json")
				itm.SetKeyString("caption", "配置主列表")
				reqHttp.ResponseAsJSON()
			} else {
				reqHttp.SetValues("code", -1, "msg", "获取配置失败!")
				reqHttp.ResponseAsJSON()
			}

			return
		}
		if json, ok := rval.(*wrapper.SuperValue); ok {
			reqHttp.Resp = json
			reqHttp.ResponseAsJSON()
		} else if bb, ok := rval.(utils.BytesBuilder); ok {
			reqHttp.RespW.Write(bb.Bytes())
			reqHttp.ResponseAsJSON()
		} else {
			reqHttp.SetValues("code", -1, "msg", "(UNKONW)获取配置失败!")
			reqHttp.ResponseAsJSON()
		}
	}

}

func OnHttpDbConfGetByID(w http.ResponseWriter, r *http.Request) {
	PrjHttpUtils.AllowCrossAccessSet(w)
	if utils.GoFunCatchException {
		defer utils.PanicHandler()
	}

	if err := AppConfService.CheckEnv(); err != nil {
		PrjHttpUtils.ResponseCodeAndMsg(w, -1, err.Error())
		return
	}

	reqHttp := PrjHttpUtils.NewHttpRec(w, r)
	reqHttp.DecodeRequestBodyAsJSON()

	strTypeID := PrjHttpUtils.GetReqParamAsString(r, reqHttp.Req, "typeid", "")

	strID := PrjHttpUtils.GetReqParamAsString(r, reqHttp.Req, "id", "")

	if len(strTypeID) == 0 {
		reqHttp.SetValues("code", -1, "msg", "必须指定typeid参数")
		reqHttp.ResponseAsJSON()
		return
	}

	err, buf := AppConfService.GetConfByID(strID, strTypeID)
	if err != nil {
		PrjHttpUtils.ResponseCodeAndMsg(w, -1, err.Error())
		return
	}
	//sqlB := db_utils.NewSQLBuilder()
	//sqlB.SelectFields("fconfig").From("sys_config")
	//sqlB.Where()
	//sqlB.EqualValues("fid", strID, "ftypeid", strTypeID)
	//
	//lvsql := sqlB.StatusString()
	//golog.Debugf(lvsql)
	//
	//blockItm := PrjDBUtils.DbBlocker.BeginUse2()
	//defer blockItm.EndUse()
	//db, err := PrjDBUtils.GetDB(DBConf_DB_ID)
	//if err != nil {
	//	PrjHttpUtils.ResponseCodeAndMsg(w, -1, err.Error())
	//	return
	//}
	//defer db.Close()
	//
	//lst, err := PrjDBUtils.GetRowList(db, lvsql)
	//if err != nil {
	//	PrjHttpUtils.ResponseCodeAndMsg(w, -1, err.Error())
	//	return
	//}

	if len(buf) == 0 {
		if reqHttp.QryAsBool("mainlist", false) {
			lst := reqHttp.Resp.ForceArrayByPath("list")
			itm := lst.AppendObject()
			itm.SetKeyString("id", strID)
			itm.SetKeyString("appid", strID)
			itm.SetKeyString("typeid", strTypeID)
			itm.SetKeyString("confAs", "json")
			itm.SetKeyString("caption", "配置主列表")
			reqHttp.ResponseAsJSON()
		} else {
			reqHttp.SetValues("code", -1, "msg", "获取配置失败!")
			reqHttp.ResponseAsJSON()
		}
		return
	}

	if len(buf) == 0 {
		reqHttp.RespW.Write([]byte("{}"))
	} else {
		reqHttp.RespW.Write(buf)
	}
}

func RegisterDBConfHttpFuncs() {
	PrjHttpUtils.HandleFunc("/sys/conf/update", OnHttpDbConfUpdate)
	PrjHttpUtils.HandleFunc("/sys/conf/list", OnHttpDbConfQryRec)     // 查询记录
	PrjHttpUtils.HandleFunc("/sys/conf/getbyid", OnHttpDbConfGetByID) // 获取配置 获取单个配置

	PrjHttpUtils.HandleFunc("/sys/conf/get", OnHttpDbConfGet) // 获取配置(一般客户获取单个配置)

}
